package com.net.xpay.web.controller.merchant;

import com.auth0.jwt.interfaces.DecodedJWT;
import com.google.common.base.Preconditions;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.net.xpay.common.model.*;
import com.net.xpay.web.vo.DevelopSettingsVo;
import com.net.xpay.web.vo.ShowDevelopSettingsVo;
import com.net.xpay.web.vo.UserProfileVo;
import com.net.common.exception.BusinessException;
import com.net.common.model.ResultData;
import com.net.xpay.common.domain.CheckCode;
import com.net.xpay.common.domain.SiteConfig;
import com.net.xpay.common.domain.User;
import com.net.xpay.common.domain.UserProfile;
import com.net.xpay.common.enums.user.CheckCodeType;
import com.net.xpay.common.manager.CheckCodeManager;
import com.net.xpay.common.manager.UserManager;
import com.net.xpay.common.manager.UserProfileManager;
import com.net.xpay.common.service.SiteConfigService;
import com.net.xpay.common.service.UserProfileService;
import com.net.xpay.common.service.UserService;
import com.net.xpay.common.util.GoogleAuthUtil;
import com.net.xpay.common.util.JWTUtil;
import com.net.xpay.common.validator.CheckCodeValidator;
import com.net.xpay.core.constant.PoseidonErrorCode;
import com.net.xpay.core.constant.WebConstant;
import com.net.xpay.core.helper.QrCodeHelper;
import com.net.xpay.core.utils.BeanCopierUtil;
import com.net.xpay.core.utils.UuidUtil;
import com.net.xpay.web.secutiry.RequestUser;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
  on 10/02/2018.
 */
@RestController
@RequestMapping("/merchant/user-profile")
@Api(tags = "公共/用户配置", description = "公共 用户配置 net")
@Slf4j
public class UserProfileController {
    @Autowired
    private UserProfileManager userProfileManager;

    @Autowired
    private UserManager userManager;

    @Autowired
    private CheckCodeValidator checkCodeValidator;

    @Autowired
    private CheckCodeManager checkCodeManager;

    @Autowired
    private QrCodeHelper qrCodeHelper;

    @Autowired
    private SiteConfigService siteConfigService;

    @Autowired
    private UserService userService;

    @Autowired
    private UserProfileService userProfileService;


    @ApiOperation(value = "修改IP白名单")
    @PutMapping("/modify—white-ips")
    public ResultData<Boolean> modifyWhiteIps(@ApiIgnore @RequestUser User user, @RequestBody UserProfileModifyModel model) {
        CheckCode checkCode = checkCodeManager.findByMobileAndType(user.getMobile(), CheckCodeType.MODIFY_WHITE_IP);

        checkCodeValidator.validateCheckCode(checkCode, model.getCheckCode());

        String whiteIps = model.getWhiteIps();
        List<String> ips = new ArrayList<>();
        if (!Strings.isNullOrEmpty(whiteIps)) {
            whiteIps = whiteIps.trim();
            //中文逗号换成英文逗号
            whiteIps = whiteIps.replace("，", ",");
            ips = Splitter.on(",").omitEmptyStrings().trimResults().splitToList(whiteIps);
        }

        UserProfile userProfile = userProfileManager.getById(user.getId());
        userProfile.setWhiteIps(ips);
        userProfileManager.update(userProfile);
        return new ResultData<>(true);
    }

    @ApiOperation(value = "获取谷歌验证器二维码")
    @PostMapping("/get-google-auth-qr-code")
    public ResultData<String> getGoogleAuthQrCode(@ApiIgnore @RequestUser User user, @RequestBody UserProfileGetGoogleAuthModel model) {
        CheckCode checkCode = checkCodeManager.findByMobileAndType(user.getMobile(), CheckCodeType.GOOGLE_AUTH);

        checkCodeValidator.validateCheckCode(checkCode, model.getCheckCode());


        UserProfile userProfile = userProfileManager.getById(user.getId());
        if (!Boolean.TRUE.equals(userProfile.getUseGoogleAuth())) {
            throw new BusinessException(PoseidonErrorCode.PARAMETER_ILLEGAL, "尚未开通谷歌验证器，请联系客服开通");
        }

        if (!Strings.isNullOrEmpty(userProfile.getGoogleAuthQrcode())) {
            return new ResultData<>(userProfile.getGoogleAuthQrcode());
        }

        String key = GoogleAuthUtil.getKeyStr();
        try {
            SiteConfig siteConfig = siteConfigService.findSiteConfig();
            String keyUrl = GoogleAuthUtil.buildKeyUrl(user.getMobile(), key, siteConfig.getName());
            String qrCode = qrCodeHelper.genThenUpload(keyUrl);
            userProfile.setGoogleAuthKey(key);
            userProfile.setGoogleAuthQrcode(qrCode);
            userProfileManager.update(userProfile);
            return new ResultData<>(qrCode);
        } catch (IOException e) {
            log.error("getGoogleAuthQrCode qrCodeHelper.genThenUpload error|userId={}", user.getId(), e);
            throw new BusinessException(PoseidonErrorCode.PARAMETER_ILLEGAL, "系统繁忙，请稍后再试");
        }
    }

    @ApiOperation(value = "重置谷歌验证器二维码")
    @PostMapping("/reset-google-auth-qr-code")
    public ResultData<String> resetGoogleAuthQrCode(@ApiIgnore @RequestUser User user, @RequestBody UserProfileGetGoogleAuthModel model) {
        CheckCode checkCode = checkCodeManager.findByMobileAndType(user.getMobile(), CheckCodeType.GOOGLE_AUTH);

        checkCodeValidator.validateCheckCode(checkCode, model.getCheckCode());

        UserProfile userProfile = userProfileManager.getById(user.getId());
        if (!Boolean.TRUE.equals(userProfile.getUseGoogleAuth())) {
            throw new BusinessException(PoseidonErrorCode.PARAMETER_ILLEGAL, "尚未开通谷歌验证器，请联系客服开通");
        }

        String key = GoogleAuthUtil.getKeyStr();
        try {
            SiteConfig siteConfig = siteConfigService.findSiteConfig();
            String keyUrl = GoogleAuthUtil.buildKeyUrl(user.getMobile(), key, siteConfig.getName());
            String qrCode = qrCodeHelper.genThenUpload(keyUrl);
            userProfile.setGoogleAuthKey(key);
            userProfile.setGoogleAuthQrcode(qrCode);
            userProfileManager.update(userProfile);
            return new ResultData<>(qrCode);
        } catch (IOException e) {
            log.error("resetGoogleAuthQrCode qrCodeHelper.genThenUpload error|userId={}", user.getId(), e);
            throw new BusinessException(PoseidonErrorCode.PARAMETER_ILLEGAL, "系统繁忙，请稍后再试");
        }
    }

    @ApiOperation(value = "修改推送地址")
    @PutMapping("/modify—notify-url")
    public ResultData<Boolean> modifyNotifyUrl(@ApiIgnore @RequestUser User user, @RequestBody UserProfileModifyModel model) {
        CheckCode checkCode = checkCodeManager.findByMobileAndType(user.getMobile(), CheckCodeType.MODIFY_NOTIFY_URL);

        checkCodeValidator.validateCheckCode(checkCode, model.getCheckCode());

        if (Strings.isNullOrEmpty(model.getChargeNotifyUrl())) {
            throw new BusinessException(PoseidonErrorCode.PARAMETER_ILLEGAL, "推送地址不能为空");
        }
        if (model.getChargeNotifyUrl().length() > 255) {
            throw new BusinessException(PoseidonErrorCode.PARAMETER_ILLEGAL, "推送地址不能超过255个字符");
        }
        if (!model.getChargeNotifyUrl().startsWith("http://") && !model.getChargeNotifyUrl().startsWith("https://")) {
            throw new BusinessException(PoseidonErrorCode.PARAMETER_ILLEGAL, "推送地址请包涵http或者https协议头");
        }

        UserProfile userProfile = userProfileManager.getById(user.getId());
        userProfile.setChargeNotifyUrl(model.getChargeNotifyUrl().trim());
        userProfileManager.update(userProfile);
        return new ResultData<>(true);
    }

    @ApiOperation(value = "修改安全付推送地址")
    @PutMapping("/modify—safe-pay-notify-url")
    public ResultData<Boolean> modifySafePayNotifyUrl(@ApiIgnore @RequestUser User user, @RequestBody UserProfileModifyModel model) {
        CheckCode checkCode = checkCodeManager.findByMobileAndType(user.getMobile(), CheckCodeType.MODIFY_SAFE_PAY_NOTIFY_URL);

        checkCodeValidator.validateCheckCode(checkCode, model.getCheckCode());

        if (Strings.isNullOrEmpty(model.getSafePayNotifyUrl())) {
            throw new BusinessException(PoseidonErrorCode.PARAMETER_ILLEGAL, "推送地址不能为空");
        }
        if (model.getSafePayNotifyUrl().length() > 255) {
            throw new BusinessException(PoseidonErrorCode.PARAMETER_ILLEGAL, "推送地址不能超过255个字符");
        }
        if (!model.getSafePayNotifyUrl().startsWith("http://") && !model.getSafePayNotifyUrl().startsWith("https://")) {
            throw new BusinessException(PoseidonErrorCode.PARAMETER_ILLEGAL, "推送地址请包涵http或者https协议头");
        }

        UserProfile userProfile = userProfileManager.getById(user.getId());
        userProfile.setSafePayNotifyUrl(model.getSafePayNotifyUrl().trim());
        userProfileManager.update(userProfile);
        return new ResultData<>(true);
    }


    @ApiOperation(value = "获取开发设置token")
    @PostMapping("/get-develop-settings-token")
    public ResultData<String> getDevelopSettingsToken(@ApiIgnore @RequestUser User user,@RequestBody DevelopSettingsModel model)  {
        return  new ResultData<>(userProfileService.getDevelopSettingsToken(user,model));
    }

    @ApiOperation(value = "获取开发设置信息")
    @PostMapping("get-develop-settings")
    @ResponseBody
    public ResultData<DevelopSettingsVo> getDevelopSettings(@ApiIgnore @RequestUser User user, @RequestBody GetDevelopSettingsModel model) {
        Preconditions.checkArgument(model != null);
        try {
            //验证token
            DecodedJWT jwt = JWTUtil.verify(model.getToken());
            String userId = jwt.getClaim(WebConstant.DEV_TOKEN_PAYLOAD_KEY).asString();
            DevelopSettingsVo vo = new DevelopSettingsVo();

          if (!Long.valueOf(userId).equals(user.getId())){
              throw new BusinessException(PoseidonErrorCode.INVALID_DEV_TOKEN, "请重新授权");
          }else {
              BeanCopierUtil.copy(user, vo);
              //配置信息
              UserProfile userProfile = userProfileManager.getById(user.getId());
              if (userProfile == null) {
                  userProfile = userService.createUserProfile(user.getId());
              }
              vo.setOpenChargeNotify(userProfile.getOpenChargeNotify());
              vo.setChargeNotifyUrl(userProfile.getChargeNotifyUrl());
              vo.setOpenSafePayNotify(userProfile.getOpenSafePayNotify());
              vo.setSafePayNotifyUrl(userProfile.getSafePayNotifyUrl());
              vo.setWhiteIps(userProfile.getWhiteIps());
              return new ResultData<>(vo);
          }

        } catch (Exception e) {
            log.info("DevelopSettingsToken error", e);
            throw new BusinessException(PoseidonErrorCode.INVALID_DEV_TOKEN, "请重新授权");
        }


    }

    @ApiOperation(value = "显示开发设置")
    @GetMapping("show-develop-settings")
    public ResultData<ShowDevelopSettingsVo> showDevelopSettings(@ApiIgnore @RequestUser User user) {

        ShowDevelopSettingsVo vo = new ShowDevelopSettingsVo();
        vo.setAppkeyShow(!Strings.isNullOrEmpty(user.getAppkey()));
        //配置信息
        UserProfile userProfile = userProfileManager.getById(user.getId());
        if (userProfile == null) {
            userProfile = userService.createUserProfile(user.getId());
        }
        vo.setOpenChargeNotify(userProfile.getOpenChargeNotify());
        vo.setChargeNotifyUrl(userProfile.getChargeNotifyUrl());
        vo.setOpenSafePayNotify(userProfile.getOpenSafePayNotify());
        vo.setSafePayNotifyUrl(userProfile.getSafePayNotifyUrl());
        vo.setWhiteIpsShow(CollectionUtils.isNotEmpty(userProfile.getWhiteIps()));

        return new ResultData<>(vo);
    }

    @ApiOperation("设置推送地址")
    @PostMapping("/update-user-charge-notify-url")
    @ResponseBody
    public ResultData<UserProfileVo> updateChargeNotifyUrl(@ApiIgnore @RequestUser User user, @RequestBody ModifyUserProfileModel model) {
        Preconditions.checkArgument(model != null);
        try {
            //验证token
            DecodedJWT jwt = JWTUtil.verify(model.getToken());
            String userId = jwt.getClaim(WebConstant.DEV_TOKEN_PAYLOAD_KEY).asString();

            if (!Long.valueOf(userId).equals(user.getId())){
                throw new BusinessException(PoseidonErrorCode.INVALID_DEV_TOKEN, "请重新授权");
            }else {
                UserProfile userProfile = userProfileManager.getById(user.getId());
                userProfile.setOpenChargeNotify(model.getOpenChargeNotify());
                userProfile.setChargeNotifyUrl(model.getChargeNotifyUrl());

                userProfileManager.update(userProfile);
                //前端显示
                UserProfileVo userProfileVo = new UserProfileVo();
                userProfileVo.setOpenChargeNotify(userProfile.getOpenChargeNotify());
                userProfileVo.setChargeNotifyUrl(userProfile.getChargeNotifyUrl());

                return new ResultData<>(userProfileVo);
            }

        } catch (Exception e) {
            log.info("DevelopSettingsToken error", e);
            throw new BusinessException(PoseidonErrorCode.INVALID_DEV_TOKEN, "请重新授权");
        }

    }

    @ApiOperation("设置安全发推送地址")
    @PostMapping("/update-user-charge-safe-notify-url")
    @ResponseBody
    public ResultData<UserProfileVo> updateChargeSafeNotifyUrl(@ApiIgnore @RequestUser User user, @RequestBody ModifyUserProfileModel model) {
        Preconditions.checkArgument(model != null);
        try {
            //验证token
            DecodedJWT jwt = JWTUtil.verify(model.getToken());
            String userId = jwt.getClaim(WebConstant.DEV_TOKEN_PAYLOAD_KEY).asString();

            if (!Long.valueOf(userId).equals(user.getId())){
                throw new BusinessException(PoseidonErrorCode.INVALID_DEV_TOKEN, "请重新授权");
            }else {
                UserProfile userProfile = userProfileManager.getById(user.getId());
                userProfile.setOpenSafePayNotify(model.getOpenSafePayNotify());
                userProfile.setSafePayNotifyUrl(model.getSafePayNotifyUrl());

                userProfileManager.update(userProfile);
                //前端显示
                UserProfileVo userProfileVo = new UserProfileVo();
                userProfileVo.setOpenSafePayNotify(userProfile.getOpenSafePayNotify());
                userProfileVo.setSafePayNotifyUrl(userProfile.getSafePayNotifyUrl());

                return new ResultData<>(userProfileVo);
            }

        } catch (Exception e) {
            log.info("DevelopSettingsToken error", e);
            throw new BusinessException(PoseidonErrorCode.INVALID_DEV_TOKEN, "请重新授权");
        }

    }

    @ApiOperation(value = "修改IP白名单")
    @PostMapping("/update—white-ips")
    @ResponseBody
    public ResultData<Boolean> updateWhiteIps(@ApiIgnore @RequestUser User user,@RequestBody ModifyUserProfileModel model) {
        Preconditions.checkArgument(model != null);
        try {
            //验证token
            DecodedJWT jwt = JWTUtil.verify(model.getToken());
            String userId = jwt.getClaim(WebConstant.DEV_TOKEN_PAYLOAD_KEY).asString();
            DevelopSettingsVo vo = new DevelopSettingsVo();

            if (!Long.valueOf(userId).equals(user.getId())){
                throw new BusinessException(PoseidonErrorCode.INVALID_DEV_TOKEN, "请重新授权");
            }else {
                String whiteIps = model.getWhiteIps();
                List<String> ips = new ArrayList<>();
                if (!Strings.isNullOrEmpty(whiteIps)) {
                    whiteIps = whiteIps.trim();
                    //中文逗号换成英文逗号
                    whiteIps = whiteIps.replace("，", ",");
                    ips = Splitter.on(",").omitEmptyStrings().trimResults().splitToList(whiteIps);
                }

                UserProfile userProfile = userProfileManager.getById(user.getId());
                userProfile.setWhiteIps(ips);
                userProfileManager.update(userProfile);
                return new ResultData<>(true);
            }

        } catch (Exception e) {
            log.info("DevelopSettingsToken error", e);
            throw new BusinessException(PoseidonErrorCode.INVALID_DEV_TOKEN, "请重新授权");
        }
    }


    @ApiOperation(value = "修改接口秘钥")
    @PostMapping("/update—appkey")
    @ResponseBody
    public ResultData<Boolean> updateAppKey(@ApiIgnore @RequestUser User user,@RequestBody GetDevelopSettingsModel model) {
        Preconditions.checkArgument(model != null);
        try {
            //验证token
            DecodedJWT jwt = JWTUtil.verify(model.getToken());
            String userId = jwt.getClaim(WebConstant.DEV_TOKEN_PAYLOAD_KEY).asString();

            if (!Long.valueOf(userId).equals(user.getId())){
                throw new BusinessException(PoseidonErrorCode.INVALID_DEV_TOKEN, "请重新授权");
            }else {
                user.setSecret(UuidUtil.uuid());
                userManager.updateByPrimaryKeyWithVersion(user);
                return new ResultData<>(true);
            }

        } catch (Exception e) {
            log.info("DevelopSettingsToken error", e);
            throw new BusinessException(PoseidonErrorCode.INVALID_DEV_TOKEN, "请重新授权");
        }
    }
}
